+2002-02-13 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush
+ all the first validate stuff if it hasn't been done, presumably
+ someone called process_updates at a weird time.
+
+ * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+ end, avoids infinite loop when end is at the end of the buffer.
+
+ * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+ line data, we were adding it to the wrong line ("line" instead of
+ "start_line")
+
2002-02-13 Joe Shaw <joe@ximian.com>
* gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
+2002-02-13 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush
+ all the first validate stuff if it hasn't been done, presumably
+ someone called process_updates at a weird time.
+
+ * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+ end, avoids infinite loop when end is at the end of the buffer.
+
+ * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+ line data, we were adding it to the wrong line ("line" instead of
+ "start_line")
+
2002-02-13 Joe Shaw <joe@ximian.com>
* gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
+2002-02-13 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush
+ all the first validate stuff if it hasn't been done, presumably
+ someone called process_updates at a weird time.
+
+ * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+ end, avoids infinite loop when end is at the end of the buffer.
+
+ * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+ line data, we were adding it to the wrong line ("line" instead of
+ "start_line")
+
2002-02-13 Joe Shaw <joe@ximian.com>
* gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
+2002-02-13 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush
+ all the first validate stuff if it hasn't been done, presumably
+ someone called process_updates at a weird time.
+
+ * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+ end, avoids infinite loop when end is at the end of the buffer.
+
+ * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+ line data, we were adding it to the wrong line ("line" instead of
+ "start_line")
+
2002-02-13 Joe Shaw <joe@ximian.com>
* gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
+2002-02-13 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush
+ all the first validate stuff if it hasn't been done, presumably
+ someone called process_updates at a weird time.
+
+ * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+ end, avoids infinite loop when end is at the end of the buffer.
+
+ * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+ line data, we were adding it to the wrong line ("line" instead of
+ "start_line")
+
2002-02-13 Joe Shaw <joe@ximian.com>
* gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
+2002-02-13 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush
+ all the first validate stuff if it hasn't been done, presumably
+ someone called process_updates at a weird time.
+
+ * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+ end, avoids infinite loop when end is at the end of the buffer.
+
+ * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+ line data, we were adding it to the wrong line ("line" instead of
+ "start_line")
+
2002-02-13 Joe Shaw <joe@ximian.com>
* gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
+2002-02-13 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush
+ all the first validate stuff if it hasn't been done, presumably
+ someone called process_updates at a weird time.
+
+ * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+ end, avoids infinite loop when end is at the end of the buffer.
+
+ * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+ line data, we were adding it to the wrong line ("line" instead of
+ "start_line")
+
2002-02-13 Joe Shaw <joe@ximian.com>
* gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
_gtk_text_btree_check (tree);
/* Broadcast the need for redisplay before we break the iterators */
+ DV (g_print ("invalidating due to deleting some text (%s)\n", G_STRLOC));
_gtk_text_btree_invalidate_region (tree, start, end);
/* Save the byte offset so we can reset the iterators */
* we do need to store our temporary sizes. So we
* create the line data and assume a line w/h of 0.
*/
- ld = _gtk_text_line_data_new (view->layout, line);
- _gtk_text_line_add_data (line, ld);
+ ld = _gtk_text_line_data_new (view->layout, start_line);
+ _gtk_text_line_add_data (start_line, ld);
ld->width = 0;
ld->height = 0;
ld->valid = FALSE;
above. FIXME */
gtk_text_iter_forward_chars (&end, char_count_delta);
+ DV (g_print ("invalidating due to inserting some text (%s)\n", G_STRLOC));
_gtk_text_btree_invalidate_region (tree,
&start, &end);
*iter = start;
gtk_text_iter_forward_char (iter); /* skip forward past the segment */
+ DV (g_print ("invalidating due to inserting pixbuf/widget (%s)\n", G_STRLOC));
_gtk_text_btree_invalidate_region (tree, &start, iter);
}
}
void
-_gtk_text_btree_invalidate_region (GtkTextBTree *tree,
- const GtkTextIter *start,
- const GtkTextIter *end)
+_gtk_text_btree_invalidate_region (GtkTextBTree *tree,
+ const GtkTextIter *start,
+ const GtkTextIter *end)
{
BTreeView *view;
{
if (_gtk_text_tag_affects_size (tag))
{
+ DV (g_print ("invalidating due to size-affecting tag (%s)\n", G_STRLOC));
_gtk_text_btree_invalidate_region (tree, start, end);
}
else if (_gtk_text_tag_affects_nonsize_appearance (tag))
end = iter;
gtk_text_iter_forward_char (&end);
+ DV (g_print ("invalidating due to moving visible mark (%s)\n", G_STRLOC));
_gtk_text_btree_invalidate_region (mark->body.mark.tree,
&iter, &end);
}
{
/* Must be a last toggle if there was a first one. */
_gtk_text_btree_get_iter_at_last_toggle (tree, &end, tag);
+ DV (g_print ("invalidating due to tag change (%s)\n", G_STRLOC));
_gtk_text_btree_invalidate_region (tree,
&start, &end);
#ifndef GTK_TEXT_BTREE_H
#define GTK_TEXT_BTREE_H
+#if 0
+#define DEBUG_VALIDATION_AND_SCROLLING
+#endif
+
+#ifdef DEBUG_VALIDATION_AND_SCROLLING
+#define DV(x) (x)
+#else
+#define DV(x)
+#endif
+
#include <gtk/gtktextbuffer.h>
#include <gtk/gtktexttag.h>
#include <gtk/gtktextmark.h>
range_start = start;
range_end = start;
+
+ /* FIXME if you insert a range into itself, this can loop infinitely because
+ * the region being copied keeps growing as we insert. The fix is probably to create a
+ * copy of what's being inserted, or to save two regions, the region before
+ * the insertion point and the region after.
+ *
+ * http://bugzilla.gnome.org/show_bug.cgi?id=71412
+ */
+
while (TRUE)
{
gint start_offset;
{
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
+ DV (g_print ("invalidating all due to default style change (%s)\n", G_STRLOC));
gtk_text_layout_invalidate_all (layout);
}
layout->rtl_context = rtl_context;
g_object_ref (G_OBJECT (rtl_context));
+ DV (g_print ("invalidating all due to new pango contexts (%s)\n", G_STRLOC));
gtk_text_layout_invalidate_all (layout);
}
layout->screen_width = width;
+ DV (g_print ("invalidating all due to new screen width (%s)\n", G_STRLOC));
gtk_text_layout_invalidate_all (layout);
}
GtkTextLineDisplay *display;
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), NULL);
-
+ g_return_val_if_fail (line != NULL, NULL);
+
if (line_data == NULL)
{
line_data = _gtk_text_line_data_new (layout, line);
*
*/
-#define SCREEN_WIDTH(widget) text_window_get_width (GTK_TEXT_VIEW (widget)->text_window)
-#define SCREEN_HEIGHT(widget) text_window_get_height (GTK_TEXT_VIEW (widget)->text_window)
-
#if 0
#define DEBUG_VALIDATION_AND_SCROLLING
#endif
#define DV(x)
#endif
+#define SCREEN_WIDTH(widget) text_window_get_width (GTK_TEXT_VIEW (widget)->text_window)
+#define SCREEN_HEIGHT(widget) text_window_get_height (GTK_TEXT_VIEW (widget)->text_window)
+
struct _GtkTextPendingScroll
{
GtkTextMark *mark;
gdouble xalign,
gdouble yalign);
-static gboolean gtk_text_view_flush_scroll (GtkTextView *text_view);
-static void gtk_text_view_update_adjustments (GtkTextView *text_view);
-static void gtk_text_view_invalidate (GtkTextView *text_view);
+static gboolean gtk_text_view_flush_scroll (GtkTextView *text_view);
+static void gtk_text_view_update_adjustments (GtkTextView *text_view);
+static void gtk_text_view_invalidate (GtkTextView *text_view);
+static void gtk_text_view_flush_first_validate (GtkTextView *text_view);
static void gtk_text_view_update_im_spot_location (GtkTextView *text_view);
if (GTK_WIDGET_VISIBLE (text_view))
gtk_widget_queue_draw (GTK_WIDGET (text_view));
-
+
+ DV(g_print ("Invalidating due to set_buffer\n"));
gtk_text_view_invalidate (text_view);
}
DV(g_print(G_STRLOC"\n"));
if (text_view->pending_scroll == NULL)
- return FALSE;
+ {
+ DV (g_print ("in flush scroll, no pending scroll\n"));
+ return FALSE;
+ }
scroll = text_view->pending_scroll;
{
if (text_view->first_validate_idle != 0)
{
+ DV (g_print ("Removing first validate idle: %s\n", G_STRLOC));
g_source_remove (text_view->first_validate_idle);
text_view->first_validate_idle = 0;
}
if (yoffset_changed)
gtk_adjustment_value_changed (vadj);
- if (text_view->first_validate_idle != 0)
- {
- /* The GTK resize loop processes all the pending exposes right
- * after doing the resize stuff, so the idle sizer won't have a
- * chance to run. So we do the work here.
- */
-
- g_source_remove (text_view->first_validate_idle);
- text_view->first_validate_idle = 0;
-
- if (!gtk_text_view_flush_scroll (text_view))
- gtk_text_view_validate_onscreen (text_view);
- }
+ /* The GTK resize loop processes all the pending exposes right
+ * after doing the resize stuff, so the idle sizer won't have a
+ * chance to run. So we do the work here.
+ */
+ gtk_text_view_flush_first_validate (text_view);
/* widget->window doesn't get auto-redrawn as the layout is computed, so has to
* be invalidated
g_assert (text_view->onscreen_validated);
}
-static gboolean
-first_validate_callback (gpointer data)
+static void
+gtk_text_view_flush_first_validate (GtkTextView *text_view)
{
- GtkTextView *text_view = data;
-
- GDK_THREADS_ENTER ();
-
- /* Note that some of this code is duplicated at the end of size_allocate,
- * keep in sync with that.
- */
-
- DV(g_print(G_STRLOC"\n"));
+ if (text_view->first_validate_idle == 0)
+ return;
/* Do this first, which means that if an "invalidate"
* occurs during any of this process, a new first_validate_callback
* will be installed, and we'll start again.
*/
+ DV (g_print ("removing first validate in %s\n", G_STRLOC));
+ g_source_remove (text_view->first_validate_idle);
text_view->first_validate_idle = 0;
/* be sure we have up-to-date screen size set on the
DV(g_print(">Leaving first validate idle ("G_STRLOC")\n"));
g_assert (text_view->onscreen_validated);
-
}
+}
+
+static gboolean
+first_validate_callback (gpointer data)
+{
+ GtkTextView *text_view = data;
+
+ GDK_THREADS_ENTER ();
+
+ /* Note that some of this code is duplicated at the end of size_allocate,
+ * keep in sync with that.
+ */
+
+ DV(g_print(G_STRLOC"\n"));
+
+ gtk_text_view_flush_first_validate (text_view);
GDK_THREADS_LEAVE ();
static void
gtk_text_view_invalidate (GtkTextView *text_view)
-{
+{
+ DV (g_print (">Invalidate, onscreen_validated = %d now FALSE ("G_STRLOC")\n",
+ text_view->onscreen_validated));
+
text_view->onscreen_validated = FALSE;
- DV(g_print(">Invalidate, onscreen_validated = FALSE ("G_STRLOC")\n"));
-
if (!text_view->first_validate_idle)
{
text_view->first_validate_idle = g_idle_add_full (GTK_PRIORITY_RESIZE - 2, first_validate_callback, text_view, NULL);
text_view = GTK_TEXT_VIEW (data);
+ DV (g_print ("Invalidating due to layout invalidate signal\n"));
gtk_text_view_invalidate (text_view);
}
}
if (yoffset_changed)
- gtk_adjustment_value_changed (get_vadjustment (text_view));
+ {
+ DV(g_print ("Changing scroll position (%s)\n", G_STRLOC));
+ gtk_adjustment_value_changed (get_vadjustment (text_view));
+ }
/* FIXME be smarter about which anchored widgets we update */
GtkTextView *text_view;
GList *child_exposes;
GList *tmp_list;
+ GdkRegion *updates;
text_view = GTK_TEXT_VIEW (widget);
g_return_if_fail (text_view->layout != NULL);
g_return_if_fail (text_view->xoffset >= 0);
g_return_if_fail (text_view->yoffset >= 0);
-
- DV (g_print (G_STRLOC": first_validate_idle: %d\n",
- text_view->first_validate_idle));
+
+ while (text_view->first_validate_idle != 0)
+ {
+ DV (g_print (G_STRLOC": first_validate_idle: %d\n",
+ text_view->first_validate_idle));
+ gtk_text_view_flush_first_validate (text_view);
+ }
+
+ /* More regions could have become invalid in the above loop */
+ updates = gdk_window_get_update_area (text_view->text_window->bin_window);
+ if (updates)
+ {
+ GdkRectangle rect;
+
+ gdk_region_get_clipbox (updates, &rect);
+
+ gdk_rectangle_union (area, &rect, area);
+
+ gdk_region_destroy (updates);
+ }
if (!text_view->onscreen_validated)
{
- g_warning (G_STRLOC ": somehow some text lines were modified or scrolling occurred since the last validation of lines on the screen - this is a known bug, no need to report.");
+ g_warning (G_STRLOC ": somehow some text lines were modified or scrolling occurred since the last validation of lines on the screen - may be a text widget bug.");
G_BREAKPOINT ();
}
GtkTextMark *mark =
gtk_text_buffer_get_mark (get_buffer (text_view), mark_name);
+ /* This may invalidate the layout */
DV(g_print (G_STRLOC": move mark\n"));
gtk_text_buffer_move_mark (get_buffer (text_view),
mark,
DV(g_print (G_STRLOC": scrolling onscreen\n"));
gtk_text_view_scroll_mark_onscreen (text_view, mark);
}
+
+ DV (g_print ("first validate idle leaving %s is %d\n",
+ G_STRLOC, text_view->first_validate_idle));
}
static gint
/* process exposes */
if (GTK_WIDGET_REALIZED (text_view))
{
+ DV (g_print ("Processing updates (%s)", G_STRLOC));
+
if (text_view->left_window)
gdk_window_process_updates (text_view->left_window->bin_window, TRUE);
gtk_text_iter_forward_char (&next);
gtk_text_iter_forward_char (&next);
- if (gtk_text_iter_compare (&next, &end) > 0)
+ if (gtk_text_iter_compare (&next, &end) >= 0)
{
next = end;
done = TRUE;